﻿using System;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace Gmantis.Controls
{
    public static class PopupUtil
    {
        // Methods
        private static void AnchorOffset(Size elementSize, ref Point p, Anchor anchor, double overlapHorizontal, double overlapVertical, FlowDirection flowDir)
        {
            if ((anchor == Anchor.TopRight) || (anchor == Anchor.BottomRight))
            {
                double num = elementSize.Width - overlapHorizontal;
                p.X += num;
            }
            if ((anchor == Anchor.BottomLeft) || (anchor == Anchor.BottomRight))
            {
                p.Y += elementSize.Height - overlapVertical;
            }
            if (anchor == Anchor.Center)
            {
                double num2 = elementSize.Width / 2.0;
                p.X = (flowDir == FlowDirection.LeftToRight) ? (p.X + num2) : (p.X - num2);
                p.Y += elementSize.Height / 2.0;
            }
        }

        public static Point GetPosition(UIElement element, Point point)
        {
            return element.GTransformToVisual(element.GetRootVisual()).Transform(point);
        }

        public static void Position(Popup popup, Point point)
        {
            popup.HorizontalOffset = !double.IsNaN(point.X) ? point.X : popup.HorizontalOffset;
            popup.VerticalOffset = !double.IsNaN(point.Y) ? point.Y : popup.HorizontalOffset;
        }

        public static void Position(Popup popup, Anchor popupAnchor, FrameworkElement element, Anchor elementAnchor)
        {
            Point point = TestPosition(popup, popupAnchor, element, elementAnchor);
            Position(popup, point);
        }

        public static Point TestPosition(Popup popup, Anchor popupAnchor, FrameworkElement element, Anchor elementAnchor)
        {
            return TestPosition(popup, popupAnchor, element, elementAnchor, 0.0, 0.0);
        }

        public static Point TestPosition(Popup popup, Anchor popupAnchor, FrameworkElement element, Anchor elementAnchor, double overlapHorizontal, double overlapVertical)
        {
            return TestPosition(popup.Child as FrameworkElement, popupAnchor, element, elementAnchor, overlapHorizontal, overlapVertical);
        }

        public static Point TestPosition(FrameworkElement positionElement, Anchor positionAnchor, FrameworkElement element, Anchor elementAnchor, double overlapHorizontal, double overlapVertical)
        {
            try
            {
                UIElement visual = element.GetRootVisual();
                Point elementOffset = element.GTransformToVisual(visual).Transform(new Point());
                return TestPosition(positionElement, positionAnchor, element, elementAnchor, elementOffset, overlapHorizontal, overlapVertical);
            }
            catch (Exception)
            {
                return new Point();
            }
        }

        public static Point TestPosition(FrameworkElement positionElement, Anchor positionAnchor, FrameworkElement element, Anchor elementAnchor, Point elementOffset, double overlapHorizontal, double overlapVertical)
        {
            return TestPosition(positionElement, positionAnchor, element, elementAnchor, elementOffset, overlapHorizontal, overlapVertical, FlowDirection.LeftToRight);
        }

        public static Point TestPosition(FrameworkElement positionElement, Anchor positionAnchor, FrameworkElement element, Anchor elementAnchor, Point elementOffset, double overlapHorizontal, double overlapVertical, FlowDirection flowDir)
        {
            try
            {
                AnchorOffset(element.ActualSize(), ref elementOffset, elementAnchor, overlapHorizontal, overlapVertical, flowDir);
                Point p = new Point();
                if (positionElement != null)
                {
                    AnchorOffset(positionElement.ActualSize(), ref p, positionAnchor, overlapHorizontal, overlapVertical, flowDir);
                }
                Point point2 = new Point(elementOffset.X - p.X, elementOffset.Y - p.Y);
                Point position = GetPosition(element, new Point());
                Point point = new Point(point2.X - position.X, point2.Y - position.Y);
                return GetPosition(element, point);
            }
            catch (Exception)
            {
                return new Point();
            }
        }
    }
}
